package com.xja.shoppingmall.service.impl;

import com.alibaba.fastjson.JSON;
import com.xja.shoppingmall.constant.AuthorityConstant;
import com.xja.shoppingmall.constant.CommonConstant;
import com.xja.shoppingmall.service.JWTService;
import com.xja.shoppingmall.vo.LoginUserInfo;
import com.xja.shoppingmall.vo.UsernameAndPassword;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import sun.misc.BASE64Decoder;

import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.UUID;

/**
 * @author CHENCHEN
 * @title
 * @createTime 2021-12-1216:22
 */
@Slf4j
@Service
public class JWTServiceImpl implements JWTService {

    @Override
    public String generatorToken(String username, String passoword) throws Exception {
        return this.generatorToken(username, passoword, 0);
    }

    @Override
    public String generatorToken(String username, String password, int expire) throws Exception {
        //验证用户登录是否正确
        String usernameDB = "admin";
        String passwordDB = "123456";
        log.info("request get userinfo is : [{}] , [{}]", username, password);
        //如果正确, 这里的id 和 username 为数据库中查询出来的信息
        LoginUserInfo loginUserInfo = new LoginUserInfo((long) 11111, username);
        if(expire <= 0){
            expire = AuthorityConstant.DEFAULT_EXPIRE_DAY;
        }
        ZonedDateTime zdt = LocalDate.now().plus(expire, ChronoUnit.DAYS).atStartOfDay(ZoneId.systemDefault());
        Date expireDate = Date.from(zdt.toInstant());
        return Jwts.builder()
                //jwt payload -> K : V
                .claim(CommonConstant.JWT_USER_INFO_KEY, JSON.toJSONString(loginUserInfo))
                //jwt id
                .setId(UUID.randomUUID().toString())
                //jwt 过期时间
                .setExpiration(expireDate)
                //jwt 签名 -> 加密
                .signWith(getPrivateKey(), SignatureAlgorithm.RS256)
                //jwt 生成信息
                .compact();
    }

    @Override
    public String registerUserAndGeneratorToken(UsernameAndPassword usernameAndPassword) throws Exception {
        //注册成功后
        return generatorToken(usernameAndPassword.getUsername(), usernameAndPassword.getPassword());
    }

    private PrivateKey getPrivateKey() throws Exception{
        return KeyFactory
                .getInstance("RSA")
                .generatePrivate(
                        new PKCS8EncodedKeySpec(
                                new BASE64Decoder()
                                        .decodeBuffer(
                                                AuthorityConstant.PRIVATE_KEY
                                        )
                        )
                );
    }
}
